Skip to content

CodeGen: Respect function align attribute if less than preferred alignment. #149444

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

pcc
Copy link
Contributor

@pcc pcc commented Jul 18, 2025

No description provided.

Created using spr 1.3.6-beta.1
@llvmbot
Copy link
Member

llvmbot commented Jul 18, 2025

@llvm/pr-subscribers-backend-x86

Author: Peter Collingbourne (pcc)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/149444.diff

2 Files Affected:

  • (modified) llvm/lib/CodeGen/MachineFunction.cpp (+1-2)
  • (added) llvm/test/CodeGen/X86/function-align.ll (+18)
diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp
index 38ad582ba923c..429a17a9113d3 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -211,9 +211,8 @@ void MachineFunction::init() {
   ConstantPool = new (Allocator) MachineConstantPool(getDataLayout());
   Alignment = STI->getTargetLowering()->getMinFunctionAlignment();
 
-  // FIXME: Shouldn't use pref alignment if explicit alignment is set on F.
   // FIXME: Use Function::hasOptSize().
-  if (!F.hasFnAttribute(Attribute::OptimizeForSize))
+  if (!F.getAlign() && !F.hasFnAttribute(Attribute::OptimizeForSize))
     Alignment = std::max(Alignment,
                          STI->getTargetLowering()->getPrefFunctionAlignment());
 
diff --git a/llvm/test/CodeGen/X86/function-align.ll b/llvm/test/CodeGen/X86/function-align.ll
new file mode 100644
index 0000000000000..11d0e99929927
--- /dev/null
+++ b/llvm/test/CodeGen/X86/function-align.ll
@@ -0,0 +1,18 @@
+; RUN: llc -function-sections < %s | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; CHECK: .section .text.f1
+; CHECK-NOT: .p2align
+; CHECK: f1:
+define void @f1() align 1 {
+  ret void
+}
+
+; CHECK: .section .text.f2
+; CHECK-NEXT: .globl f2
+; CHECK-NEXT: .p2align 1
+define void @f2() align 2 {
+  ret void
+}

@pcc pcc requested review from arsenm and efriedma-quic July 18, 2025 03:45
// FIXME: Use Function::hasOptSize().
if (!F.hasFnAttribute(Attribute::OptimizeForSize))
if (!F.getAlign() && !F.hasFnAttribute(Attribute::OptimizeForSize))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will also disrespect getMinFunctionAlignment which is probably more of a problem

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applying this in the function constructor also seems like the wrong place to do this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see why it doesn't respect getMinFunctionAlignment. getMinFunctionAlignment is read on line 212 and combined with the preferred alignment with std::max here, so the result will be at least getMinFunctionAlignment.

@pcc pcc merged commit 9878ef3 into main Jul 18, 2025
12 checks passed
@pcc pcc deleted the users/pcc/spr/codegen-respect-function-align-attribute-if-less-than-preferred-alignment branch July 18, 2025 20:33
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Jul 18, 2025
…ferred alignment.

Reviewers: arsenm, efriedma-quic

Reviewed By: arsenm

Pull Request: llvm/llvm-project#149444
@efriedma-quic
Copy link
Collaborator

This has a side-effect you might not want.

Due to the way member function pointers work in the Itanium ABI, all member functions must have at least 2 byte alignment. clang represents this by marking each member function "align 2". This used to allow increasing the alignment if it wasn't specified, but with this patch, all member functions have exactly 2-byte alignment.

@pcc
Copy link
Contributor Author

pcc commented Jul 18, 2025

Interesting. I had not considered that consequence.

I think longer term we will want a way for frontends to query the subtarget's minimum and preferred alignment. Then here clang could query the right one based on whether it's optimizing for size and set the align attribute to the max of that and 2.

Maybe for now we can introduce a min-align attribute and have clang set it to 2 on member functions.

@efriedma-quic
Copy link
Collaborator

The alignment is queried directly by optimizations through getPointerAlignment; I don't think we can decrease it after the fact.

I'd suggest adding an attribute in the opposite direction; for functions where we don't want the alignment to increase, add a function attribute "minimize-alignment", and the backend won't increase alignment for those functions.

@efriedma-quic
Copy link
Collaborator

Oh, also, on the subject of function alignment, we currently still have

// If the function alignment is not specified then assume that it
. We should update the x86 datalayout so that hack isn't necessary, but it hasn't been a priority for me.

@pcc
Copy link
Contributor Author

pcc commented Jul 19, 2025

The alignment is queried directly by optimizations through getPointerAlignment; I don't think we can decrease it after the fact.

The idea is that min-align would only be capable of increasing the function alignment, not decreasing it. For example, given a function with min-align 2, on x86 with -Os we would end up with alignment 2 and x86 without -Os would have alignment 16, and on aarch64 the alignment would still always be at least 4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants